        TITL DAI FIRMWARE D8FB-DAD3  V1.1
        ORG   :D8FB
*
*
*
*  ===================
*** INTERRUPT HANDLER ***
*  ===================
*
*
*******************************
* INITIALISE INTERRUPT SYSTEM *
*******************************
*
* Initialises the interrupt system of the machine.
*
* Entry: No conditions.
* Exit:  All registers corrupted.
*
INTINI  LXI   H,:FFF8   Address int.mask register
        MVI   A,:04
        MOV   M,A       Only stack interrupt
        STA   :005F     Remember int. mask
        MVI   L,:F4
        MVI   A,:0C
        MOV   M,A       Select ext.int. and INTA
        INR   A
        MOV   M,A       Reset
        MVI   A,:0C
        STA   :01C0     Init. cursor timer
        MVI   A,:02
        STA   :01C1     Init. keyboard scan counter
        CALL  :D9A3     Reload sound timer
        CALL  :D99D     Reload keyboard timer
        CALL  :D949     Set up int. entry points
 REM
* Set-up interrupt vectors (also entry from utility)
 REM
INTSU   LXI   H,:D9A9
        SHLD  :0070     Clock int. vector (7)
        LXI   H,:D578
        SHLD  :006E     Keyboard int. vector (6)
        LXI   H,:C6FD
        SHLD  :006C     Screen restart vector (5)
        LXI   H,:C6C0
        SHLD  :006A     Math. restart vector (4)
        LXI   H,:D755
        SHLD  :0068     Sound int. vector (3)
        LXI   H,:D9E2
        SHLD  :0066     Stack int. vector (2)
        LXI   H,:C70E
        SHLD  :0064     Utility/encode vector (1)
        RET
*
* SET UP INTERRUPT VECTOR AREA:
*
* Sets up the vector area 0000-003F.
*
* Entry: No conditions.
* Exit:  All registers corrupted.
*
VECSU   LXI   B,:0000   Start at zero
VCS10   LXI   D,:D96B   Startaddr. int. routine
        LXI   H,:D973   Endaddress
        CALL  :DE4F     Transfer int. routine
        MOV   A,C
        CPI   :40       8 routines done?
        JNZ   :D94C     Next one if not ready
        LXI   H,:003B   Addr. highest int.vector
        LXI   B,:FFF8
        MVI   D,:70
VCS20   MOV   M,D       Load vector addr.
        DCR   D
        DCR   D
        DAD   B         Calculate next addr
        JC    :D963     Next one if not ready
        RET
*
* INTERRUPT VECTOR ROUTINE:
*
* During initialisation loaded into RAM on the
* Restart routine locations of the CPU.
* The address after LHLD is later changed into
* the appropriate vector address by #D8FB.
*
ITMPL   NOP
        PUSH  H
        LHLD  :0070
        PCHL
        NOP
        NOP
*
*******************************
* DISABLE KEYBOARD INTERRUPTS *
*******************************
*
* Disables keyboard interrupts only.
*
* Entry can be different. From INTCH common part
* to disable/enable sound, clock and keyboard
* interrupts.
*
* Entry: None.
* Exit:  All registers preserved.
*
KBDI    PUSH  B
        LXI   B,:BF00   Disable keyboard interrupts
*
INTCH   PUSH  PSW
        DI              Disable interrupts
        LDA   :005F     Get current int.mask
        ANA   B         ) Calculate new one
        ORA   C         )
        STA   :005F     Remember new mask
        STA   :FFF8     and set mask
        EI              Enable interrupts again
        POP   PSW
        POP   B
        RET
*
******************************
* ENABLE KEYBOARD INTERRUPTS *
******************************
*
* Enables keyboard interrupts only.
*
KBEI    PUSH  B
        LXI   B,:FF40   Enable keyboard interrupts
        JMP   :D977     Update int. mask
*
****************************
* DISABLE SOUND INTERRUPTS *
****************************
*
* Disables sound interrupts only.
*
SNDDI   PUSH  B
        LXI   B,:F700   Disable sound interrupts
        JMP   :D977     Update int. mask
*
***************************
* ENABLE SOUND INTERRUPTS *
***************************
*
* Enables sound interrupts only.
*
SNDEI   PUSH  B
        LXI   B,:FF08   Enable sound interrupts
        JMP   :D977     Update int. mask
*
***********************
* LOAD KEYBOARD TIMER *
***********************
*
* Starts a keyboard interrupt.
*
KBIS    MVI   A,:FF     Init. 16.32 msec
        STA   :FFFC     Load timer 4 (keyboard)
        RET
*
********************
* LOAD SOUND TIMER *
********************
*
* Starts a sound interrupt.
*
SNDIS   MVI   A,:50     Init. 5.12 msec
        STA   :FFFB     Load timer 3 (sound)
        RET
*
***************************
* CLOCK INTERRUPT (RST 7) *
***************************
*
* Triggered every 20 msec by the TV page
* blanking signal.
* Decrements timer 01BE/BF until 0. Checks also
* the contents of cursor clock timer 01C0. It is
* decremented, if it becomes 0, the timer is re-
* loaded and the cursor is flashed.
*
* Exit: All registers preserved.
*
CLKINT  PUSH  PSW
        PUSH  B
        PUSH  D
        LDA   :005F     Get current int. mask
        PUSH  PSW       and remember it
        MVI   A,:04
        STA   :FFF8     Set stack interrupt only
        EI
        LHLD  :01BE     Get timer contents
        MOV   A,H
        ORA   L
        JZ    :D9C2     If timer = 0
        DCX   H         Else:
        SHLD  :01BE     decrement timer
CKI10   LXI   H,:01C0   Addr. cursor clock
        DCR   M         Decr. clock
        JNZ   :D9CD     Return if <>0
        MVI   M,:0F     Load 20 ms flash time
        RST   5         Flash cursor
        DATA  :12
*
* GENERAL INTERRUPT RETURN:
*
* Restores interrupt mask and all registers.
*
* Entry: Interrupt mask and all registers on stack.
*
INTRM   POP   PSW       Get old int. mask
        DI
        STA   :FFF8     Restore int. mask
        STA   :005F     and remember it.
        EI
        POP   D
        POP   B
        POP   PSW
        POP   H
        RET
*
**************************
* ENABLE CLOCK INTERRUPT *
**************************
*
CLKEI   PUSH  B
        LXI   B,:FF80   Enable clock interrupt
        JMP   :D977     Update int.mask
*
**************************
* STACK INTERRUPT (RST2) *
**************************
*
* This routine handles an interrupt caused by the
* stack overflow hardware logic.
*
SPINT   LXI   SP,:F900  Reset stackpointer
        XRA   A
        STA   :0117     No running inputs
        STA   :0122     No encoding of stored line
        CALL  :D743     Input from keyboard, reload
 REM timers sound/keyb
        EI
        MVI   A,:16
        JMP   :D9F5     Run error 'STACK OVERFLOW'
*
*
*
*
*  ===============
*** ERROR HANDLER ***
*  ===============
*
*
******************
* ERROR HANDLING *
******************
*
* Produces an error message and other information
* about errors.
*
* Entry: A:  Error message number.
*        BC: Latest position in EBUF or textbuffer.
* Exit:  If during input: Restart input statement.
*        If during encoding: Back to ELINA (C93C)
*                            for handling.
*        Else: Restart Basic (direct mode).
*
ERROR   MOV   B,A       Save error pointer
        XRA   A
        STA   :0131     Set output screen/RS232
        CALL  :CEE4     Select ROM bank 0
        DBL   :0000
        NOP
        NOP
        LDA   :0118     Get RUNF
        ORA   A
        JNZ   :DA3D     If run-time error
        JMP   :DA64     If compile-time error
*
* ENTRYPOINTS TO ERROR ROUTINES:
*
ERRSN   MVI   A,:17
        JMP   :D9F5     Run 'SYNTAX ERROR'
*
ERROM   MVI   A,:13
        JMP   :D9F5     Run 'OUT OF MEMORY'
*
ERRRA   MVI   A,:09
        JMP   :D9F5     Run 'NUMBER OUT OF RANGE'
*
ERRTM   MVI   A,:14
        JMP   :D9F5     Run 'TYPE MISMATCH'
*
ERROV   MVI   A,:03
        JMP   :D9F5     Run 'OVERFLOW'
*
ERRD0   MVI   A,:06
        JMP   :D9F5     Run 'DIVISION BY ZERO'
*
ERRBS   MVI   A,:05
        JMP   :D9F5     Run 'SUBSCRIPT ERROR'
*
ERRNF   MVI   A,:00
        JMP   :D9F5     Run 'NEXT WITHOUT FOR'
*
ERREL   MVI   A,:12
        JMP   :D9F5     Run 'ERROR LINE RUN'
*
ERRLS   MVI   A,:08
        JMP   :D9F5     Run 'STRING TOO LONG'
*
******************
* RUN-TIME ERROR *
******************
*
ERRRU   CALL  :DA50     Print error message
        LDA   :0117     Get RDIPL
        ORA   A
        JNZ   :DA4D     Jump if running inputs
        CALL  :DA75     else: Print 'IN LINE <nr>'
        JMP   :C814     Re-enter BASIC
 REM
* If error in input:
 REM
ERT10   JMP   :E350     (0) Back to restart input
*
***********************
* PRINT ERROR MESSAGE *
***********************
*
* Entry: B: Error message number.
* Exit:  BC preserved, AFDEHL corrupted.
*
ERRMS   CALL  :DD55     Cursor to begin (next) line
        MOV   A,B       Get error number
        LXI   H,:DA94   Base of list error messages
        ADD   A         Multiply error nr *2
        MOV   E,A       and save offset
        MVI   D,:00
        DAD   D         Calculate table addr.
        MOV   E,M       ) Get addr of message
        INX   H         ) in DE
        MOV   D,M       )
        XCHG            and in HL
        CALL  :DAD4     Print error message
        RET
*
**********************
* COMPILE-TIME ERROR *
**********************
*
* Handles errors in direct mode. Only an error
* message is printed. Control is passed back to
* ELINA (C93C) except if it is an error during
* encoding of a stored line.
*
* Entry: A: Error number.
*        C: Points to last read character on
*           input line.
* Exit:  To Basic interpreter.
*
ERRCO   LDA   :0122     Get ERSFL
        CPI   :01       Error during encoding?
        JZ    :C957     Then handle error
 REM
* Error in direct command:
 REM
        CALL  :DA50     Print error message
        CALL  :DD5E     Print car.ret
        JMP   :C823     Restart interpreter
*
 REM
********************************************
* PRINT LINE NUMBER IN WHICH ERROR OCCURED *
********************************************
*
* Prints car.ret if current line is a direct command.
* Else, prints 'IN LINE <linenr>' and car.ret.
*
* Entry: None.
* Exit:  ABCDEHL preserved. F corrupted.
*        Z=1: direct command.
*
MSGIL   PUSH  H     
        PUSH  PSW
        LHLD  :0100     Get start current line
        MOV   A,H
        ORA   L         Check if 0
        PUSH  PSW
        JZ    :DA8C     If direct, print car.ret
        CALL  :DAFF     Else, print 'IN LINE'
        DBL   :DB7F
        MOV   A,M       ) Get line nr in HL
        INX   H         )
        MOV   L,M       )
        MOV   H,A       )
        CALL  :EFB4     (0) Print line number
MIL10   CALL  :DD5E     Print car.ret
        POP   PSW
        POP   H
        MOV   A,H
        POP   H
        RET
*
************************************
* ERROR MESSAGES INDIRECTION TABLE *
************************************
*
* The address points to the location where the
* string with the error messages can be found.
* Between brackets the error number.
*
* Run-time errors:
*ERITB
E?NF    DBL   :DC1C     (00) NEXT WITHOUT FOR
E?RG    DBL   :DC2C     (01) RETURN WITHOUT GOSUB
E?OD    DBL   :DC33     (02) OUT OF DATA
E?OV    DBL   :DC3E     (03) OVERFLOW
E?US    DBL   :DC50     (04) UNDEFINED LINE NUMBER
E?BS    DBL   :DC5C     (05) SUBSCRIPT ERROR
E?D0    DBL   :DC68     (06) DIVISION BY ZERO
E?OS    DBL   :DC95     (07) OUT OF STRING SPACE
E?LS    DBL   :DC9D     (08) STRING TOO LONG
E?RA    DBL   :DCD8     (09) NUMBER OUT OF RANGE
E?IN    DBL   :DCB2     (0A) INVALID NUMBER
E?LO0   DBL   :DCFA     (0B) LOADING ERROR 0
E?LO1   DBL   :DCFE     (0C) LOADING ERROR 1
E?LO2   DBL   :DD02     (0D) LOADING ERROR 2
E?LO3   DBL   :DD06     (0E) LOADING ERROR 3
E?UA    DBL   :DCF1     (0F) UNDEFINED ARRAY
E?NC    DBL   :DCC2     (10) COLOUR NOT AVAILABLE
E?OF    DBL   :DCB7     (11) OFF SCREEN
E?EL    DBL   :DD12     (12) ERROR LINE RUN
 REM
* Compile/Run-time errors:
 REM
E?OM    DBL   :DC47     (13) OUT OF MEMORY
E?TM    DBL   :DC8A     (14) TYPE MISMATCH
E?LN    DBL   :DCD6     (15) LINE NUMBER OUT OF
 REM .    RANGE
E?SO    DBL   :DC38     (16) STACK OVERFLOW
 REM
* Compile-time errors:
 REM
E?SN    DBL   :DC23     (17) SYNTAX ERROR
E?ID    DBL   :DC79     (18) COMMAND INVALID
E?CN    DBL   :DCA9     (19) CAN'T CONT
E?TC    DBL   :DCE3     (1A) LINE TOO COMPLEX
E?ST    DBL   :DC47     (1B) OUT OF MEMORY
*
*******************************
* WAIT; part of RTALK (0EC6D) *
*******************************
*
* Entry: HL: Wait time.
*
 REM
* If wait:
* As old routine, but HL replaced by DE.
 REM
RTK20   DCX   D         ]
        MOV   A,D       ]
        ORA   E         ]
        JNZ   :DACC     ] Wait for DE=0
        RET             ]
        DATA  :FF       ]
*
*
*
        UNL
ERITB   EQU E?NF
        LST
        END
